/*
 * @Author       : Deng
 * @Date         : 2023-05-16 13:34:48
 * @LastEditors  : Joel
 * @LastEditTime : 2024-09-24 00:40:22
 * @FilePath     : \app\main.c
 * @Description  :
 * Copyright 2024 YiJiaLink, All Rights Reserved.
 * 2023-05-16 13:34:48
 */

#include <string.h>
#include "binary_tree.h"
#include <oxygen_ml.h>
#include "hlw8012.h"
#include "md5.h"
#include "linklist.h"
#include "user_timer.h"
#include "desmos.h"
#include "test.h"
#include "test.h"
#include "rectangle.h"
#include "at_esp32.h"

static int get_analysis_len(unsigned char bytes[]);
static int greate_packages_len(int num, unsigned char *data);
static char *Int2String(int num, char *str);

static short get_index_hlw8012_v2p_value(short frequency);

#pragma pack(1)
typedef struct _data_type
{
    /* data */
    unsigned char data0;
    short data1;
} data_type;
typedef union _data_union
{
    struct
    {
        unsigned char datai0;
        short datai1;
        unsigned char datai3;
    } data_type1;
    // 结构体指针测试
    unsigned char bytes_test[100];
} data_union;
/* OTA_TCP升级登录 */
typedef struct _taihe_ota_server
{
    uint8_t head_start;
    uint16_t length;
    uint8_t opcode;
    union
    {
        struct
        {
            uint8_t device_length;
            uint8_t device_code2[10];
            uint8_t key_flag;
            uint8_t zip_flag;
            uint8_t soft_number;
            uint8_t hardw_number;
            uint16_t authcode;
            uint8_t head_end;
            /* data */
        } login;
        struct
        {
            uint32_t start_size;
            uint16_t file_length;
            uint8_t ota_process;
            uint8_t head_end;
            /* data */
        } get_file;
        struct
        {
            uint8_t exit;
            uint8_t head_end;
        } exit_ota;
        /* data */
    } opcode_data;

    /* data */
} taihe_ota_server;

/* 登录包解析 */
typedef struct _ota_server_received
{
    uint8_t head_start;
    uint16_t length;
    uint8_t opcode;
    union
    {
        struct
        {
            uint8_t code_result;
            uint8_t soft_number;
            uint8_t hardw_number;
            uint8_t md5_length;
            char md5_data[32];
            uint32_t file_size;
            uint8_t head_end;
            /* data */
        } login;

        struct
        {
            uint32_t start_size;
            uint16_t data_len;
            uint8_t state_code;
            uint8_t data[256];
            uint8_t head_end;
            /* data */
        } get_file;

        struct
        {
            uint8_t exit_result;
            uint8_t head_end;
            /* data */
        } logout;

    } back_data;
    /* data */
} ota_server_received;
// AT_OTA连接
typedef enum
{
    SERVER_CLOSED,
    OTA_LOGIN,
    OTA_GET_FILE,
    OTA_EXIT
} FIRMWARE_OTA;
#pragma pack()

/* 登录包 */
taihe_ota_server start_ota = {
    .head_start = 0x06,
    .length = 0x13,
    .opcode = 0,
    .opcode_data.login.device_length = 10,
    .opcode_data.login.device_code2 = "2022B00000",
    .opcode_data.login.key_flag = 0,
    .opcode_data.login.zip_flag = 0,
    .opcode_data.login.soft_number = 9,
    .opcode_data.login.hardw_number = 9,
    .opcode_data.login.authcode = 9463,
    .opcode_data.login.head_end = 0x0d};
taihe_ota_server *ota_p;
char *p = NULL;

ota_server_received *ota_received_p = NULL;

// 模拟解析登录包
uint8_t login[512] = {
    0x06, 0x2A, 0x00, 0x00, 0x01, 0x0A, 0x02, 0x20, 0x30, 0x65, 0x39, 0x30, 0x31, 0x61, 0x35, 0x63, 0x37, 0x35, 0x65, 0x37, 0x35, 0x61, 0x39, 0x64, 0x61, 0x62, 0x34, 0x33, 0x66, 0x33, 0x61,
    0x33, 0x65, 0x36, 0x31, 0x38, 0x33, 0x39, 0x31, 0x37, 0xCC, 0x24, 0x01, 0x00, 0x0D};
// 模拟解析文件包
uint8_t getfile[512] = {
    0x06, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D};
// 模拟解析退出
uint8_t exit_ota[512] = {
    0x06, 0x03, 0x00, 0x02, 0x00, 0x0D};
// OTA发送与解析
void ota_testing(void)
{
    unsigned char j, *p;

    printf("\r\n ");
    printf("client_login\r\n");
    ota_p = &start_ota;
    p = (char *)ota_p;
    j = 0;
    do
    {
        /* code */
        printf(" %02x ", p[j]);
        j++;
    } while (j < (ota_p->length + 3) /* condition */);
    printf("\r\n\r\n ");
    printf("client_get_file\r\n");
    ota_p->length = 9;
    ota_p->opcode = 1;
    ota_p->opcode_data.get_file.file_length = 1;
    ota_p->opcode_data.get_file.ota_process = 0;
    ota_p->opcode_data.get_file.start_size = 0;
    ota_p->opcode_data.get_file.head_end = 0x0d;
    j = 0;
    do
    {
        /* code */
        printf(" %02x ", p[j]);
        j++;
    } while (j < (ota_p->length + 3) /* condition */);
    printf("\r\n\r\n ");
    printf("client_exit_ota\r\n");
    ota_p->length = 3;
    ota_p->opcode = 2;
    ota_p->opcode_data.exit_ota.exit = 0;
    ota_p->opcode_data.exit_ota.head_end = 0x0d;
    j = 0;
    do
    {
        /* code */
        printf(" %02x ", p[j]);
        j++;
    } while (j < (ota_p->length + 3) /* condition */);
    printf("\r\n\r\n ");
    // uint8_t code_result;
    // uint8_t soft_number;
    // uint8_t hardw_number;
    // uint8_t md5_length;
    // uint8_t md5_data[32];
    // uint32_t file_size;
    // uint8_t head_end;
    char md5_data[33];
    printf("server_login>>>>\r\n ");
    ota_received_p = (ota_server_received *)&login;
    printf("start %02x\n ", ota_received_p->head_start);
    printf("length %d\n ", ota_received_p->length);
    printf("opcode %02x\n ", ota_received_p->opcode);
    printf("login.code_result %d\n ", ota_received_p->back_data.login.code_result);
    printf("login.soft_number %d\n ", ota_received_p->back_data.login.soft_number);
    printf("login.hardw_number %d\n ", ota_received_p->back_data.login.hardw_number);
    printf("login.md5_length %d\n ", ota_received_p->back_data.login.md5_length);
    snprintf(md5_data, ota_received_p->back_data.login.md5_length + 1, ota_received_p->back_data.login.md5_data);
    printf("login.md5_data %s\r\n ", md5_data);
    printf("login.file_size %d\n ", ota_received_p->back_data.login.file_size);
    printf("login.head_end %02x\n\r\n ", ota_received_p->back_data.login.head_end);

    printf("server_getfile>>>>\r\n ");
    ota_received_p = (ota_server_received *)&getfile;
    static uint8_t data_index;
    printf("start %02x\n ", ota_received_p->head_start);
    printf("length %d\n ", ota_received_p->length);
    printf("opcode %02x\n ", ota_received_p->opcode);
    printf("get_file.start_size %d\n ", ota_received_p->back_data.get_file.start_size);
    printf("get_file.data_len %d\n ", ota_received_p->back_data.get_file.data_len);
    printf("get_file.state_code %02x\n ", ota_received_p->back_data.get_file.state_code);
    data_index = 0;
    do
    {
        /* code */
        printf("back_data.get_file.data [%d] = %02x\n ", data_index, ota_received_p->back_data.get_file.data[data_index]);
        data_index++;
    } while (data_index < ota_received_p->back_data.get_file.data_len /* condition */);
    ota_received_p->back_data.get_file.head_end = ota_received_p->back_data.get_file.data[data_index++];
    printf("get_file.head_end %02x\n\r\n ", ota_received_p->back_data.get_file.head_end);

    printf("server_exit_ota>>>>\r\n ");
    ota_received_p = (ota_server_received *)&exit_ota;
    printf("start %02x\n ", ota_received_p->head_start);
    printf("length %d\n ", ota_received_p->length);
    printf("opcode %02x\n ", ota_received_p->opcode);
    printf("get_file.exit_result %d\n ", ota_received_p->back_data.logout.exit_result);
    printf("get_file.head_end %02x\n ", ota_received_p->back_data.logout.head_end);
}

#include <math.h>
/**
 * @func:
 * @description:
 * @param {int} input1
 * @return {*}
 * @example:
 */
int timu2B(int input1)
{

    int input2 = 0;
    int test = input1;
    // 编辑框2的值 = m((转成浮点数(编辑框1) / 1024)0.5 * 1024)

    float i = (float)test;
    i = (double)(i / 1024);
    printf("i= %4f", i);
    printf("result= %4f", sqrt(i));
    input2 = (int)(sqrt(i) * 1024);
    printf("input2= %d\r\n", input2);
    return input2;
}
void timu3B(int input1)
{
    int input2 = 0;
    int num, index = 8;
    num = input1;
    while (index > 0 /* condition */)
    {
        /* code */
        if (!(num % 2))
            input2++;
        num = num >> 1;
        index--;
    }

    printf("input2： %d", input2);
}
/**
 * @description:
 * @return {*}
 */
unsigned char hexbuf[128] = {0x00, 0xc0, 0x00, 0x20};
/**
 * @description: 主函数
 * @return {*}
 */
uint8_t red[PWM_CYCLE * 8];
uint8_t green[PWM_CYCLE * 8];
uint8_t blue[PWM_CYCLE * 8];
int main(void)
{
    static uint8_t j = 0;
    if (++j > 50)
        ;
    else if (++j < 2)
        ;
    printf("j = %d\r\n", j);
    linklist_test_main();
    timu2B(1);
    timu3B(5);
    printf("\r\n");
    /* cjson test */

    // cjson_test();
    // printf("read_bin_test>>>>\r\n ");
    // ota_flash_md5_testint(hexbuf,4);
    //  printf("V= %d\r\n",index);
    // tree_array_test();
    //  printf("value= %f",do_ml_switch(0.966,37.09));
    // greate_packages_len(130,bytes);
    // printf("bytes= %x\r\n",bytes[0]);
    // printf("bytes= %x\r\n",bytes[1]);
    // printf("hello world\r\n");
    // printf("中文测试\r\n");
    // 计算功率
    // printf("value= %d\r\n",(short)algorithm_hlw8012_power_value(1300,220));
    // test_user_timer();
    printf("x=[");
    for (uint16_t i = 0; i < PWM_CYCLE * 8; i++)
        printf("%d,", i);
    printf("]\r\n");
    // PWM_CYCLE * 8 为x 轴长度
    for (uint16_t i = 0; i < PWM_CYCLE * 8; i++)
    {
        static uint8_t flag, data = 1;
        if (i % 128 == 0)
        {
            ++flag;
            // 正弦与余弦函数切换波形
            if (flag == 1)
                data = !data;
            // 三色周期0-2
            else if (flag > 2)
                flag = 0;
        }

        switch (flag)
        {
        case 0 /* constant-expression */:
            /* code */
            blue[i] = (uint8_t)get_apm_value(i, 510, data);
            green[i] = (uint8_t)get_apm_value(i, 510, !data);
            break;
        case 1 /* constant-expression */:
            /* code */

            red[i] = (uint8_t)get_apm_value(i, 510, data);
            blue[i] = (uint8_t)get_apm_value(i, 510, !data);
            break;
        case 2 /* constant-expression */:
            /* code */
            red[i] = (uint8_t)get_apm_value(i, 510, data);
            green[i] = (uint8_t)get_apm_value(i, 510, !data);
            break;
        default:
            break;
        }
    }
    printf("red=[");
    for (uint16_t i = 0; i < PWM_CYCLE * 8; i++)
        printf("%d,", red[i]);
    printf("]\r\n");

    printf("green=[");
    for (uint16_t i = 0; i < PWM_CYCLE * 8; i++)
        printf("%d,", green[i]);
    printf("]\r\n");

    printf("blue=[");
    for (uint16_t i = 0; i < PWM_CYCLE * 8; i++)
        printf("%d,", blue[i]);
    printf("]\r\n");

    // rectangle_test();
    head = cmd_initLink(cmd_init, AT_END);
    at_loop(head);

    // rgb_duty_run();
    return 0;
}
/**
 * @description:
 * @param {short} frequency
 * @return {*}
 */
static short get_index_hlw8012_v2p_value(short frequency)
{
    // V2P公式通过频率真反推导出 V2P参数电压
    static float index_v2p = 0.00;
    index_v2p = (frequency / 6.9);
    printf("index_v2p= %2f", index_v2p);
    index_v2p = (1215 * index_v2p);
    printf("index_v2p= %2f", index_v2p);
    index_v2p = index_v2p * RESISTOR_VALUE / RESISTOR_DOWN;
    index_v2p = index_v2p / HLW8012_RATE;
    printf("index_v2p= %2f", index_v2p);
    // 转为16位返回
    return (short)index_v2p;
}

/**
 * @description: 获取解析包长度
 * @param {u_char} bytes
 * @return {*} 长度
 */
static int get_analysis_len(unsigned char bytes[])
{

    int remainingLength = 0;
    unsigned char multiplier = 1;
    short digit;
    unsigned char loops = 0;
    // 解包的算法
    do
    {
        digit = (short)bytes[loops];
        remainingLength += (digit & 127) * multiplier;
        multiplier *= 128;
        loops++;
    } while ((digit & 128) != 0 && loops < 2);
    printf("recieived_length= %d\n\r\n\r\n", remainingLength);
    return remainingLength;
}
/**
 * @description: 构建解析包长度
 * @param {u_char} bytes num:输入需要计算的长度，*data:得到的数组
 * @return {*} 返回 0
 */
static int greate_packages_len(int num, unsigned char *data)
{
    unsigned char index = 0;

    unsigned char digit;
    do
    {
        digit = (unsigned char)(num % 128);
        num /= 128;
        if (num > 0)
        {
            digit |= 0x80;
        }
        printf("digit=%02x\n", digit);
        data[index] = digit;
        index++;

    } while (num > 0);

    return 0;
}

// 计算 |p1 p2| X |p1 p|
